<template>
  <div class="cron-generator">
    <h2>Cron表达式生成器</h2>
    <div class="feature-group">
      <label class="feature-label">工具说明:</label>
      <ul class="feature-list">
        <li class="feature-item">输入秒、分、时、日、月、周等字段，生成Cron表达式。</li>
        <li class="feature-item">支持秒、分、时、日、月、周、年的范围</li>
        <li class="feature-item">支持秒、分、时、日、月、周、年的间隔。</li>
      </ul>
    </div>
    <div class="form-group">
      <!-- 顶部标签切换 -->
      <div class="tabs">
        <label
            v-for="(label, index) in tabLabels"
            :key="index"
            :class="{ active: currentTab === label }"
            @click="currentTab = label"
        >
          {{ label }}
        </label>
      </div>

      <!-- 动态渲染当前标签对应的内容 -->
      <div class="cron-field" v-if="currentTab">
        <div v-if="currentTab === '秒'">
          <h3>秒钟</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="secondOption" value="*"> 每秒允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="secondOption" value="range"> 周期从
              <input v-model.number="secondRangeFrom" type="number" min="0" max="59" placeholder="0">
              -
              <input v-model.number="secondRangeTo" type="number" min="0" max="59" placeholder="59">
              秒
            </label>
            <label>
              <input type="radio" v-model="secondOption" value="interval"> 从
              <input v-model.number="secondIntervalFrom" type="number" min="0" max="59" placeholder="0">
              秒开始，每
              <input v-model.number="secondIntervalStep" type="number" min="1" max="59" placeholder="1">
              秒执行一次
            </label>
            <label>
              <input type="radio" v-model="secondOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 59" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedSeconds" @change="secondOption = 'specific'">
                  {{ i }}
                </label>
              </div>
            </label>
          </div>
        </div>

        <div v-if="currentTab === '分钟'">
          <h3>分钟</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="minuteOption" value="*"> 每分钟允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="minuteOption" value="range"> 周期从
              <input v-model.number="minuteRangeFrom" type="number" min="0" max="59" placeholder="0">
              -
              <input v-model.number="minuteRangeTo" type="number" min="0" max="59" placeholder="59">
              分钟
            </label>
            <label>
              <input type="radio" v-model="minuteOption" value="interval"> 从
              <input v-model.number="minuteIntervalFrom" type="number" min="0" max="59" placeholder="0">
              分钟开始，每
              <input v-model.number="minuteIntervalStep" type="number" min="1" max="59" placeholder="1">
              分钟执行一次
            </label>
            <label>
              <input type="radio" v-model="minuteOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 59" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedMinutes" @change="minuteOption = 'specific'">
                  {{ i }}
                </label>
              </div>
            </label>
          </div>
        </div>

        <div v-if="currentTab === '小时'">
          <h3>小时</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="hourOption" value="*"> 每小时允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="hourOption" value="range"> 周期从
              <input v-model.number="hourRangeFrom" type="number" min="0" max="23" placeholder="0">
              -
              <input v-model.number="hourRangeTo" type="number" min="0" max="23" placeholder="23">
              小时
            </label>
            <label>
              <input type="radio" v-model="hourOption" value="interval"> 从
              <input v-model.number="hourIntervalFrom" type="number" min="0" max="23" placeholder="0">
              小时开始，每
              <input v-model.number="hourIntervalStep" type="number" min="1" max="23" placeholder="1">
              小时执行一次
            </label>
            <label>
              <input type="radio" v-model="hourOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 23" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedHours" @change="hourOption = 'specific'">
                  {{ i }}
                </label>
              </div>
            </label>

          </div>
        </div>

        <div v-if="currentTab === '日'">
          <h3>日</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="dayOption" value="*"> 每日允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="dayOption" value="range"> 周期从
              <input v-model.number="dayRangeFrom" type="number" min="1" max="31" placeholder="1">
              -
              <input v-model.number="dayRangeTo" type="number" min="1" max="31" placeholder="31">
              日
            </label>
            <label>
              <input type="radio" v-model="dayOption" value="interval"> 从
              <input v-model.number="dayIntervalFrom" type="number" min="1" max="31" placeholder="1">
              日开始，每
              <input v-model.number="dayIntervalStep" type="number" min="1" max="31" placeholder="1">
              日执行一次
            </label>
            <label>
              <input type="radio" v-model="dayOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 31" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedDays" @change="dayOption = 'specific'">
                  {{ i }}
                </label>
              </div>
            </label>
          </div>
        </div>

        <div v-if="currentTab === '月'">
          <h3>月</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="monthOption" value="*"> 每月允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="monthOption" value="range"> 周期从
              <input v-model.number="monthRangeFrom" type="number" min="1" max="12" placeholder="1">
              -
              <input v-model.number="monthRangeTo" type="number" min="1" max="12" placeholder="12">
              月
            </label>
            <label>
              <input type="radio" v-model="monthOption" value="interval"> 从
              <input v-model.number="monthIntervalFrom" type="number" min="1" max="12" placeholder="1">
              月开始，每
              <input v-model.number="monthIntervalStep" type="number" min="1" max="12" placeholder="1">
              月执行一次
            </label>
            <label>
              <input type="radio" v-model="monthOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 12" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedMonths" @change="monthOption = 'specific'">
                  {{ i }}
                </label>
              </div>
            </label>
          </div>
        </div>

        <div v-if="currentTab === '周'">
          <h3>周</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="weekdayOption" value="*"/>
              每周允许的通配符 [ * ]（任务将在每周的每一天执行）<br>
            </label>
            <label>
              <input type="radio" v-model="weekdayOption" value="range"/>
              周期从
              <input v-model.number="weekdayRangeFrom" type="number" min="0" max="6" placeholder="0"/>
              -
              <input v-model.number="weekdayRangeTo" type="number" min="0" max="6" placeholder="6"/>
              周（任务将在该范围内的每一天执行）
            </label>
            <label>
              <input type="radio" v-model="weekdayOption" value="interval"/>
              从星期
              <input v-model.number="weekdayIntervalFrom" type="number" min="0" max="6" placeholder="0"/>
              开始，每
              <input v-model.number="weekdayIntervalStep" type="number" min="1" max="6" placeholder="1"/>
              周执行一次（任务将从指定的星期开始，以固定的间隔执行）
            </label>
            <label>
              <input type="radio" v-model="weekdayOption" value="specific"/> 指定
              <div class="specific-values">
                <label v-for="i in 6" :key="i">
                  <input type="checkbox" :value="i" v-model="selectedWeekdays" @change="weekdayOption = 'specific'"/>
                  {{
                    i === 0 ? '日' : i === 1 ? '一' : i === 2 ? '二' : i === 3 ? '三' : i === 4 ? '四' : i === 5 ? '五' : '六'
                  }}
                </label>
              </div>
            </label>
          </div>
        </div>

        <div v-if="currentTab === '年'">
          <h3>年</h3>
          <div class="options">
            <label>
              <input type="radio" v-model="yearOption" value="*"> 每年允许的通配符 [ * ] <br>
            </label>
            <label>
              <input type="radio" v-model="yearOption" value="range"> 周期从
              <input v-model.number="yearRangeFrom" type="number" min="2025" max="2099" placeholder="2025">
              -
              <input v-model.number="yearRangeTo" type="number" min="2025" max="2099" placeholder="2099">
              年
            </label>
            <label>
              <input type="radio" v-model="yearOption" value="interval"> 从
              <input v-model.number="yearIntervalFrom" type="number" min="2025" max="2040" placeholder="2025">
              年开始，每
              <input v-model.number="yearIntervalStep" type="number" min="1" max="100" placeholder="1">
              年执行一次
            </label>
            <label>
              <input type="radio" v-model="yearOption" value="specific"> 指定
              <div class="specific-values">
                <label v-for="i in 25" :key="i">
                  <input type="checkbox" :value="i+2024" v-model="selectedYears" @change="yearOption = 'specific'">
                  {{ 2024 + i }}
                </label>
              </div>
            </label>
          </div>
        </div>

      </div>

      <!-- 生成Cron表达式按钮 -->
      <button @click="generateCron">生成Cron表达式</button>
    </div>
    <!-- 显示生成的表达式 -->
    <div class="cron-output-group">
      <h3 class="cron-output-title">生成结果</h3>
      <table class="cron-output">
        <thead>
        <tr>
          <td></td>
          <td>秒</td>
          <td>分钟</td>
          <td>小时</td>
          <td>日</td>
          <td>月</td>
          <td>周</td>
          <td>年</td>
        </tr>
        </thead>
        <tbody>
        <tr>
          <th>字段：</th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
          <th>
            <pre>*</pre>
          </th>
        </tr>
        </tbody>
      </table>
      <div class="cron-output-text"><strong>Cron表达式：</strong>
        <pre>{{ cronExpression }}</pre>
      </div>
      <p class="cron-output-text"><strong>表达式解析：</strong>{{ cronExplanation }}</p>
    </div>
    <div class="cron-output-group">
      <h3>常用Cron表达式：</h3>
        <p>（1）<strong>0 0 2 1 * ?</strong>&nbsp;表示在每月的1日的凌晨2点调整任务</p>
        <p>（2）<strong>0 15 10 ? * MON-FRI</strong>&nbsp;表示周一到周五每天上午10:15执行作业</p>
        <p>（3）<strong>0 15 10 ? 6L 2002-2006</strong>&nbsp;表示2002-2006年的每个月的最后一个星期五上午10:15执行作</p>
        <p>（4）<strong>0 0 10,14,16 * * ?</strong>&nbsp;每天上午10点，下午2点，4点</p>
        <p>（5）<strong>0 0/30 9-17 * * ?</strong>&nbsp;朝九晚五工作时间内每半小时</p>
        <p>（6）<strong>0 0 12 ? * WED</strong>&nbsp;表示每个星期三中午12点</p>
        <p>（7）<strong>0 0 12 * * ?</strong>&nbsp;每天中午12点触发</p>
        <p>（8）<strong>0 15 10 ? * *&nbsp;</strong>每天上午10:15触发</p>
        <p>（9）<strong>0 15 10 * * ?</strong>&nbsp;每天上午10:15触发</p>
        <p>（10）<strong>0 15 10 * * ?</strong>&nbsp;每天上午10:15触发</p>
        <p>（11）<strong>0 15 10 * * ? 2005</strong>&nbsp;2005年的每天上午10:15触发</p>
        <p>（12）<strong>0 * 14 * * ?</strong>&nbsp;在每天下午2点到下午2:59期间的每1分钟触发</p>
        <p>（13）<strong>0 0/5 14 * * ?</strong>&nbsp;在每天下午2点到下午2:55期间的每5分钟触发</p>
        <p>（14）<strong>0 0/5 14,18 * * ?</strong>&nbsp;在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发</p>
        <p>（15）<strong>0 0-5 14 * * ?</strong>&nbsp;在每天下午2点到下午2:05期间的每1分钟触发</p>
        <p>（16）<strong>0 10,44 14 ? 3 WED</strong>&nbsp;每年三月的星期三的下午2:10和2:44触发</p>
        <p>（17）<strong>0 15 10 ? * MON-FRI</strong>&nbsp;周一至周五的上午10:15触发</p>
        <p>（18）<strong>0 15 10 15 * ?</strong>&nbsp;每月15日上午10:15触发</p>
        <p>（19）<strong>0 15 10 L * ?</strong>&nbsp;每月最后一日的上午10:15触发</p>
        <p>（20）<strong>0 15 10 ? * 6L</strong>&nbsp;每月的最后一个星期五上午10:15触发</p>
        <p>（21）<strong>0 15 10 ? * 6L 2002-2005</strong>&nbsp;2002年至2005年的每月的最后一个星期五上午10:15触发</p>
        <p>（22）<strong>0 15 10 ? * 6#3</strong>&nbsp;每月的第三个星期五上午10:15触发</p>

    </div>
  </div>
</template>
<script setup>
import cronstrue from 'cronstrue/i18n.js';

// 顶部标签
const tabLabels = ['秒', '分钟', '小时', '日', '月', '周', '年'];
const currentTab = ref('秒');

// 数据绑定 - 秒
const secondOption = ref('*');
const secondRangeFrom = ref(0);
const secondRangeTo = ref(59);
const secondIntervalFrom = ref(0);
const secondIntervalStep = ref(1);
const selectedSeconds = ref([]);

// 数据绑定 - 分钟
const minuteOption = ref('*');
const minuteRangeFrom = ref(0);
const minuteRangeTo = ref(59);
const minuteIntervalFrom = ref(0);
const minuteIntervalStep = ref(1);
const selectedMinutes = ref([]);

// 数据绑定 - 小时
const hourOption = ref('*');
const hourRangeFrom = ref(0);
const hourRangeTo = ref(23);
const hourIntervalFrom = ref(0);
const hourIntervalStep = ref(1);
const selectedHours = ref([]);

// 数据绑定 - 日
const dayOption = ref('*');
const dayRangeFrom = ref(1);
const dayRangeTo = ref(31);
const dayIntervalFrom = ref(1);
const dayIntervalStep = ref(1);
const selectedDays = ref([]);

// 数据绑定 - 月
const monthOption = ref('*');
const monthRangeFrom = ref(1);
const monthRangeTo = ref(12);
const monthIntervalFrom = ref(1);
const monthIntervalStep = ref(1);
const selectedMonths = ref([]);

// 数据绑定 - 年
const yearOption = ref('*');
const yearRangeFrom = ref(2025);
const yearRangeTo = ref(2099);
const yearIntervalFrom = ref(2025);
const yearIntervalStep = ref(1);
const selectedYears = ref([]);

// 数据绑定 - 周
const weekdayOption = ref('*');
const weekdayRangeFrom = ref(0);
const weekdayRangeTo = ref(6);
const weekdayIntervalFrom = ref(0);
const weekdayIntervalStep = ref(1);
const selectedWeekdays = ref([]);

const cronExpression = ref('');

// 解释完整的 Cron 表达式
const generateCronExpression = () => {
  return `${generateSecondExpression()} ${generateMinuteExpression()} ${generateHourExpression()} ${generateDayExpression()} ${generateMonthExpression()} ${generateWeekdayExpression()} ${generateYearExpression()}`;
};

const cronExplanation = computed(() => {
  const fullCronExpression = generateCronExpression();
  // 直接使用 cronstrue 进行解释，不需要 setLocale
  return cronstrue.toString(fullCronExpression, { locale: 'zh_CN' });
});

// 生成各个部分的Cron表达式
const generateSecondExpression = () => {
  switch (secondOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${secondRangeFrom.value}-${secondRangeTo.value}`;
    case 'interval':
      return `${secondIntervalFrom.value}/${secondIntervalStep.value}`;
    case 'specific':
      return selectedSeconds.value.join(',');
    default:
      return '*';
  }
};

const generateMinuteExpression = () => {
  switch (minuteOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${minuteRangeFrom.value}-${minuteRangeTo.value}`;
    case 'interval':
      return `${minuteIntervalFrom.value}/${minuteIntervalStep.value}`;
    case 'specific':
      return selectedMinutes.value.join(',');
    default:
      return '*';
  }
};

const generateHourExpression = () => {
  switch (hourOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${hourRangeFrom.value}-${hourRangeTo.value}`;
    case 'interval':
      return `${hourIntervalFrom.value}/${hourIntervalStep.value}`;
    case 'specific':
      return selectedHours.value.join(',');
    default:
      return '*';
  }
};

const generateDayExpression = () => {
  switch (dayOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${dayRangeFrom.value}-${dayRangeTo.value}`;
    case 'interval':
      return `${dayIntervalFrom.value}/${dayIntervalStep.value}`;
    case 'specific':
      return selectedDays.value.join(',');
    default:
      return '*';
  }
};

const generateMonthExpression = () => {
  switch (monthOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${monthRangeFrom.value}-${monthRangeTo.value}`;
    case 'interval':
      return `${monthIntervalFrom.value}/${monthIntervalStep.value}`;
    case 'specific':
      return selectedMonths.value.join(',');
    default:
      return '*';
  }
};

const generateWeekdayExpression = () => {
  switch (weekdayOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${weekdayRangeFrom.value}-${weekdayRangeTo.value}`;
    case 'interval':
      return `${weekdayIntervalFrom.value}/${weekdayIntervalStep.value}`;
    case 'specific':
      // Cron中的星期日为7，但在选择时我们用0表示，因此需要转换
      return selectedWeekdays.value.map(day => day === 0 ? '7' : day).join(',');  // Cron中的星期日为7
    default:
      return '*';
  }
};

const generateYearExpression = () => {
  switch (yearOption.value) {
    case '*':
      return '*';
    case 'range':
      return `${yearRangeFrom.value}-${yearRangeTo.value}`;
    case 'interval':
      return `${yearIntervalFrom.value}/${yearIntervalStep.value}`;
    case 'specific':
      return selectedYears.value.join(',');
    default:
      return '*';
  }
};

// 生成完整的Cron表达式
const generateCron = () => {
  const secondPart = generateSecondExpression();
  const minutePart = generateMinuteExpression();
  const hourPart = generateHourExpression();
  const dayPart = generateDayExpression();
  const monthPart = generateMonthExpression();
  const weekdayPart = generateWeekdayExpression();
  const yearPart = generateYearExpression();

  cronExpression.value = `${secondPart} ${minutePart} ${hourPart} ${dayPart} ${monthPart} ${weekdayPart} ${yearPart}`;
};

</script>

<style scoped>
.cron-generator {
  max-width: 1000px;
  width: calc(100% - 60px);
  margin: 40px auto 10px auto;
  padding: 20px;
  font-family: Arial, sans-serif;
  background-color: #fff;
  border-radius: 4px;
}

h2 {
  margin-bottom: 20px;
  text-align: center;
  font-size: 24px;
  color: #17a2b8;
}

.feature-group {
  margin-bottom: 20px;
}

.feature-label {
  display: inline-block;
  margin-bottom: 5px;
  font-weight: bold;
  border-left: 4px solid #17a2b8;
  padding-left: 10px;
}

.feature-list {
  margin: 0;
  padding: 10px 20px;
  border-radius: 4px;
}

.feature-item {
  margin: 0 0 8px 20px;
  font-size: 14px;
  line-height: 1.5;
  list-style-type: disc; /* 列表符号 */
}

.feature-list::marker {
  color: #007bff; /* 圆点颜色 */
  font-size: 16px; /* 圆点大小 */
}

/* 如果你有具体的列表内容，可以在这里添加 */
.feature-list ul {
  margin: 0;
  padding: 0;
  list-style-type: none; /* 先去掉默认样式 */
}

.feature-list ul li::before {
  content: '•'; /* 添加圆点 */
  color: #007bff; /* 圆点颜色 */
  display: inline-block;
  width: 1em;
  margin-left: -1em;
  font-size: 16px; /* 圆点大小 */
}

.form-group {
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 20px;
  background-color: #f9f9f9;
}


.tabs {
  display: flex;
}

.tabs label {
  padding: 10px 20px;
  border: 1px solid #ddd;
  border-bottom: none;
  cursor: pointer;
}

.tabs label.active {
  background-color: #42b983;
  color: white;
  border: 1px solid #42b983;
}

.cron-field {
  margin-top: 20px;
}

h3 {
  margin-bottom: 10px;
  font-weight: 700;
}

.options {
  display: flex;
  flex-direction: column;
}

.specific-values {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
}

button {
  padding: 10px 20px;
  background-color: #42b983;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 4px;
  margin-top: 20px;
}

button:hover {
  background-color: #369867;
}

.cron-output-group {
  margin-top: 20px;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 20px;
}

.cron-output {
  margin-top: 20px;
  text-align: left;
  border-radius: 4px;
  padding: 15px;
}

.cron-output table {
  width: 100%;
}


.cron-output th,
.cron-output td {
  padding: 8px;
  width: 150px;
  text-align: center;
}

.cron-output tr {
  border-bottom: 1px solid #ddd;
}

.cron-output-title {
  margin-bottom: 10px;
  font-size: 16px;
  font-weight: bold;
  background-color: #4299e1;
  color: white;
  padding: 10px;
}

.cron-output pre {
  margin: 0;
  padding: 0;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.cron-output-text {
  display: flex;
  margin: 10px 0;
  border-bottom: 1px solid #ddd;
  padding: 10px;
}

.cron-output-text strong {
  font-size: 14px;
  margin-right: 10px;
  flex: 0 0 1;
}

.cron-output-text pre {
  flex: 1;
  margin: 0;
  padding: 0 10px;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}
@media (max-width: 480px) {
  .tabs{
    padding: 0;
  }
  .tabs label{
    padding: 10px 12px;
    font-size: 12px;
  }
  .specific-values{
    grid-template-columns: repeat(4, 1fr);
  }
  .cron-output-group{
    padding: 10px;
    font-size: 12px;
  }
  .cron-output th,
  .cron-output td{
     padding: 6px;
     width: 120px;
  }
}
</style>